/**
 * 
 */
package com.witframework.dynoengine;

import java.sql.DatabaseMetaData;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.witframework.core.AppInitializer;
import com.witframework.core.WitFrameWork;
import com.witframework.core.logic.IBaseService;
import com.witframework.core.persistence.Filter;
import com.witframework.core.persistence.JdbcTools;
import com.witframework.dynoengine.model.WitMetaColumn;
import com.witframework.dynoengine.model.WitMetaTable;

/**
 * @author wuxinyang Jul 8, 2009 11:07:27 AM
 */

public class MetaInitializer implements AppInitializer {
	private static Log log = LogFactory.getLog(MetaInitializer.class);
	public void execute() {
		long s = System.currentTimeMillis();	
		initBaseMeta();
		initMeta();
		log.info("基本元数据初始化完成:" + (System.currentTimeMillis() - s) + "ms");		
	}	
	private static boolean isPk(String tableName,String columnName){
		List<Map> primaryKeys=JdbcTools.getTableMetaData(tableName,"PKS");
		for(Map m:primaryKeys){
			String cn=(String)m.get("COLUMN_NAME");
			if(cn.equalsIgnoreCase(columnName))
				return true;
		}
		return false;
	}
	private static String getImportKeyInfo(String tableName,String columnName){
		List<Map> primaryKeys=JdbcTools.getTableMetaData(tableName,"IKS");
		for(Map m:primaryKeys){
			String cn=(String)m.get("FKCOLUMN_NAME");
			if(cn.equalsIgnoreCase(columnName))
				return m.get("PKTABLE_NAME")+"."+m.get("PKCOLUMN_NAME");
		}
		return "";
	}
	private void initBaseMeta() {			
		IBaseService tableService = WitFrameWork.getSimpleBaseService(WitMetaTable.class);
		IBaseService columnService = WitFrameWork.getSimpleBaseService(WitMetaColumn.class);
		List<Map> tables=JdbcTools.getTables();
		for(Map tableMap:tables){
			String table_name=(String)tableMap.get("TABLE_NAME");//TABLE_NAME String => 表名称 
			String table_remarks=(String)tableMap.get("REMARKS");//REMARKS String => 表的解释性注释 
			String table_type=(String)tableMap.get("TABLE_TYPE");//TABLE_TYPE String => 表类型
			if (tableService.getBy("tableName", table_name.toUpperCase())==null) {
				WitMetaTable witMetaTable = new WitMetaTable();
				witMetaTable.setTableName(table_name.toUpperCase());
				witMetaTable.setTableTitle(table_remarks);			
				witMetaTable.setTableType(table_type);
				tableService.save(witMetaTable);	
			
			
				List<Map> columns=JdbcTools.getColumnMetaData(table_name);
				for(Map columnMap:columns){
					String TABLE_NAME=(String)columnMap.get("TABLE_NAME");//TABLE_NAME String => 表名称 
					String COLUMN_NAME=(String)columnMap.get("COLUMN_NAME");//COLUMN_NAME String => 列名称 
					Integer DATA_TYPE=(Integer)columnMap.get("DATA_TYPE");//DATA_TYPE int => 来自 java.sql.Types 的 SQL 类型 
					String TYPE_NAME=(String)columnMap.get("TYPE_NAME");//数据源依赖的类型名称，对于 UDT，该类型名称是完全限定的
					Integer COLUMN_SIZE=(Integer)columnMap.get("COLUMN_SIZE");//列的大小。 
					Integer DECIMAL_DIGITS=(Integer)columnMap.get("DECIMAL_DIGITS");//小数部分的位数。对于 DECIMAL_DIGITS 不适用的数据类型，则返回 Null。 
					String REMARKS=(String)columnMap.get("REMARKS");//REMARKS String => 描述列的注释（可为 null） 
					String COLUMN_DEF=(String)columnMap.get("COLUMN_DEF");//COLUMN_DEF String => 该列的默认值，当值在单引号内时应被解释为一个字符串（可为 null） 
					String IS_AUTOINCREMENT=(String)columnMap.get("IS_AUTOINCREMENT");//IS_AUTOINCREMENT String => 指示此列是否自动增加YES --- 如果该列自动增加 NO --- 如果该列不自动增加 空字符串 --- 如果不能确定该列是否是自动增加参数 
					Integer NULLABLE=(Integer)columnMap.get("NULLABLE");//int => 是否允许使用 NULL。 columnNoNulls - 可能不允许使用 NULL 值 columnNullable - 明确允许使用 NULL 值 columnNullableUnknown - 不知道是否可使用 null 
					 

					Map filter=new Filter().put("tableName", TABLE_NAME.toUpperCase()).put("columnName", COLUMN_NAME.toUpperCase()).toMap();					
					if (columnService.findBy(filter).size()==0){				
						WitMetaColumn c=new WitMetaColumn();							
						c.setTableName(TABLE_NAME.toUpperCase());
						c.setColumnName(COLUMN_NAME.toUpperCase());
						c.setColumnType(DATA_TYPE);
						c.setColumnTypeName(TYPE_NAME);
						c.setColumnTitle(REMARKS);		
						c.setColumnSize(COLUMN_SIZE);
						c.setColumnPrecision(DECIMAL_DIGITS);
						c.setColumnDefaultValue(COLUMN_DEF);		
						c.setIsAutoIncrement(IS_AUTOINCREMENT);
						c.setIsDisplayable("Y");
						c.setFkey(getImportKeyInfo(TABLE_NAME,COLUMN_NAME));
						c.setFkeyViewColumn("");
						c.setIsListable("Y");
						c.setIsNullable(DatabaseMetaData.typeNullable==NULLABLE?"Y":"N");
						c.setIsPkey(isPk(TABLE_NAME,COLUMN_NAME)?"Y":"N");
						c.setIsPviewColumn(COLUMN_NAME.equalsIgnoreCase("name")?"Y":"N");
						c.setIsQueryable("Y");
						c.setIsResultable("Y");
						c.setIsEditable("Y");
						c.setIsSortable("Y");
						c.setIsUnique(c.getIsPkey().equalsIgnoreCase("Y")?"Y": "N");
						c.setDisplaySort(100);
						
						c.setValidation("required");
						columnService.save(c);	
					}
				}
			}
		}
		
		if (true) {
			WitMetaTable t = (WitMetaTable)tableService.getBy("tableName", "WIT_META_TABLE");
			t.setTableTitle("表的元数据");			
			
			WitMetaColumn c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_TABLE").put("columnName", "TABLE_NAME").toMap());
			c.setColumnTitle("表名称");		
			c.setColumnSize(50);
			c.setIsEditable("N");
			c.setDisplaySort(1);
			tableService.saveOrUpdate(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_TABLE").put("columnName", "TABLE_TITLE").toMap());
			c.setColumnTitle("标题");				
			c.setTipText("表的中文名称");
			c.setDisplaySort(2);
			tableService.saveOrUpdate(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_TABLE").put("columnName", "DATA_SOURCE_NAME").toMap());
			c.setColumnTitle("数据源");			
			c.setTipText("数据源的名称,不同的表可以有不同的数据源");
			c.setDisplaySort(10);
			tableService.saveOrUpdate(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_TABLE").put("columnName", "STATUS").toMap());
			c.setColumnTitle("状态(Y/N)");			
			c.setTipText("是否在用");
			c.setDisplaySort(10);
			tableService.saveOrUpdate(c);
		
		
			t = (WitMetaTable)tableService.getBy("tableName", "WIT_META_COLUMN");
			t.setTableTitle("表的列的元数据");			
			tableService.update(t);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "TABLE_NAME").toMap());
			c.setColumnTitle("表名称");			
			c.setTipText("数据库中的表名");
			c.setIsEditable("N");
			c.setDisplaySort(1);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "COLUMN_NAME").toMap());
			c.setColumnTitle("列名称");		
			c.setTipText("数据库表的列的名称");
			c.setIsEditable("N");
			c.setDisplaySort(2);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "COLUMN_TITLE").toMap());
			c.setColumnTitle("列标题");		
			c.setTipText("列的中文名称");
			c.setDisplaySort(3);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "COLUMN_TYPE").toMap());
			c.setColumnTitle("列类型");		
			c.setIsEditable("N");
			c.setDisplaySort(4);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "COLUMN_TYPE_NAME").toMap());
			c.setColumnTitle("列类型名称");	
			c.setIsEditable("N");
			c.setDisplaySort(5);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "COLUMN_SIZE").toMap());
			c.setColumnTitle("列长度");			
			c.setDisplaySort(6);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "COLUMN_PRECISION").toMap());
			c.setColumnTitle("列小数位长");			
			c.setIsEditable("N");
			c.setDisplaySort(7);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "COLUMN_DEFAULT_VALUE").toMap());
			c.setColumnTitle("默认值");	
			c.setTipText("列的默认值");
			c.setDisplaySort(8);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "GROUP_NAME").toMap());
			c.setColumnTitle("组名");	
			c.setTipText("不同的组将会在不同的fieldset中显示");
			c.setDisplaySort(9);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "IS_PKEY").toMap());
			c.setColumnTitle("是否主键");	
			c.setIsEditable("N");
			c.setDisplaySort(10);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "FKEY_VIEW_COLUMN").toMap());
			c.setColumnTitle("外键主显示列");	
			c.setTipText("引用的外键在显示是对应的列，如引用user表的id时实际应显示name列。");
			c.setDisplaySort(10);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "IS_PVIEW_COLUMN").toMap());
			c.setColumnTitle("是否主显示列");	
			c.setTipText("在该表的主键作为外键被引用时，该列是否显示用列，参见：外键主显示列");
			c.setDisplaySort(10);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "IS_AUTO_INCREMENT").toMap());
			c.setColumnTitle("是否自增列");		
			c.setTipText("对于自增列，在插入数据时数据库会自动产生一个序列值");
			c.setIsEditable("N");
			c.setDisplaySort(10);
			tableService.update(c);
			

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "FKEY").toMap());
			c.setColumnTitle("外键");	
			c.setTipText("是否外键");
			c.setIsEditable("N");
			c.setDisplaySort(11);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "IS_UNIQUE").toMap());
			c.setColumnTitle("是否唯一");			
			c.setDisplaySort(12);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "IS_NULLABLE").toMap());
			c.setColumnTitle("是否可空");	
			c.setTipText("该列是否可以为空值");
			c.setDisplaySort(13);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "IS_EDITABLE").toMap());
			c.setColumnTitle("是否可修改");	
			c.setTipText("是否允许在应用程序界面手动维护该列的值");
			c.setDisplaySort(14);
			tableService.update(c);


			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "IS_LISTABLE").toMap());
			c.setColumnTitle("是否可列印");	
			c.setTipText("是否在数据列表页面显示该字段");
			c.setDisplaySort(40);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "IS_QUERYABLE").toMap());
			c.setColumnTitle("是否可查询");			
			c.setTipText("是否在查询条件中显示该列为查询字段");
			c.setDisplaySort(40);
			tableService.update(c);


			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "IS_RESULTABLE").toMap());
			c.setColumnTitle("是否可在查询结果");			
			c.setTipText("在所有查询该表数据时，是否包含该列。");
			c.setDisplaySort(40);
			tableService.update(c);


			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "IS_SORTABLE").toMap());
			c.setColumnTitle("是否可排序");	
			c.setTipText("在数据列表页面是否可以按照该列进行排序");
			c.setDisplaySort(40);
			tableService.update(c);
			

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "DISPLAY_SORT").toMap());
			c.setColumnTitle("显示顺序");			
			c.setTipText("字段列在所有需要显示的界面上的显示顺序");
			c.setDisplaySort(50);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "DISPLAY_SIZE").toMap());
			c.setColumnTitle("显示宽度");		
			c.setTipText("字段列在所有需要显示的界面上显示宽度");
			c.setDisplaySort(50);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "CELL_STYLE").toMap());
			c.setColumnTitle("显示样式");			
			c.setTipText("指定字段列在所有需要显示的界面上显示时的样式");
			c.setDisplaySort(50);
			tableService.update(c);
			

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "SELECT_CLASS").toMap());
			c.setColumnTitle("选择器");			
			c.setDisplaySort(60);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "SELECT_TYPE").toMap());
			c.setColumnTitle("选择类型");		
			c.setTipText("类型可以是：select(单选)、mselect(多选)、tree(树形单选)、mtree(树形多选)、checkbox、mcheckbox");
			c.setDisplaySort(60);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "SELECT_PARAM").toMap());
			c.setColumnTitle("选择器参数");		
			c.setTipText("传递给选择器的参数：对于select 、checkbox可以是vp(值,文本)或sql类型，如vp=value,text;value,text;或" +
					"sql=select id value,name text from user。" +
					"对于tree(树形单选)、mtree(树形多选)待定 ");
			c.setDisplaySort(60);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "FORMAT_CLASS").toMap());
			c.setColumnTitle("格式化器");			
			c.setDisplaySort(60);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "TIP_TEXT").toMap());
			c.setColumnTitle("字段填写提示信息");		
			c.setTipText("正如你现在看到的文字，就是程序的提示信息");
			c.setDisplaySort(70);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "VALIDATION").toMap());
			c.setColumnTitle("验证器串");	
			c.setTipText("具体内容待定");
			c.setDisplaySort(80);
			tableService.update(c);

			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "VALIDATION_CLASS").toMap());
			c.setColumnTitle("验证器类");			
			c.setTipText("具体内容待定");
			c.setDisplaySort(80);
			tableService.update(c);
			
			c=(WitMetaColumn)columnService.findObjectBy(new Filter().put("tableName", "WIT_META_COLUMN").put("columnName", "COLUMN_DESC").toMap());
			c.setColumnTitle("说明");	
			c.setTipText("在这里填写说明性文字");
			c.setDisplaySort(100);
			tableService.update(c);
			
		}
		
	}
	private void initMeta() {		
		IBaseService sbs = WitFrameWork.getSimpleBaseService(WitMetaTable.class);
		if (sbs.getAll().size() == 0) {
			WitMetaTable t = (WitMetaTable)sbs.getBy("tableName", "AD_USER".toUpperCase());
			t.setTableTitle("系统用户");
			sbs.update(t);	
			sbs = WitFrameWork.getSimpleBaseService(WitMetaColumn.class);
			WitMetaColumn c=(WitMetaColumn)sbs.findObjectBy(
					new Filter().put("tableName",t.getTableName()).put("columnName", "USERNAME").toMap());			
			c.setColumnTitle("用户");
			c.setIsListable("Y");
			c.setIsSortable("Y");
			c.setDisplaySort(1);
			sbs.update(c);
			c=(WitMetaColumn)sbs.findObjectBy(
					new Filter().put("tableName",t.getTableName()).put("columnName", "NAME").toMap());				
			c.setColumnTitle("姓名");
			c.setIsListable("Y");
			c.setIsSortable("Y");
			c.setDisplaySort(2);
			sbs.update(c);
			c=(WitMetaColumn)sbs.findObjectBy(
					new Filter().put("tableName",t.getTableName()).put("columnName", "DESCRIPTION").toMap());				
			c.setColumnTitle("说明");
			c.setIsListable("Y");
			c.setIsSortable("Y");
			c.setDisplaySort(10);
			sbs.update(c);
		}
		
	}
	
	public static void main(String[] avg) {
		new MetaInitializer().execute();
	}
}

    

